import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.LinkedList;

/**
 * Created by hasee on 2017/8/22.
 */
public class Snake extends LinkedList{
    Yard yard;
    static Snake snake;
    static boolean isAlive=true; //蛇状态。true表示活,false表示死
    static int score=0;//表示游戏分数;
    boolean isKeyLive=true;//蛇死后,把isKeyLive设成fales,锁死键盘

        public Snake(Yard yard, int cro, int ver, Dir dir){
        this.yard=yard;
        snake=this;
        Node head = new Node(cro,ver,dir);
        snake.addFirst(head);
    }

    public void addToHead(){//蛇头前+1方块
        while (snake.size()==0){return;}
        Node head = (Node) snake.getFirst();
        Node node= new Node(1,1, Dir.R);
        switch (head.dir){
            case L:node.cro=head.cro;node.ver=head.ver-1;node.dir=head.dir;break;
            case U:node.cro=head.cro-1;node.ver=head.ver;node.dir=head.dir;break;
            case R:node.cro=head.cro;node.ver=head.ver+1;node.dir=head.dir;break;
            case D:node.cro=head.cro+1;node.ver=head.ver;node.dir=head.dir;break;
        }
        snake.addFirst(node);
    }

    public void addToTail(){//蛇尾后+1方块
        if (snake.size()==0){return;}
        Node tail = (Node) snake.getLast();
        Node node = new Node(1,1, Dir.R);
        switch (tail.dir){
            case L:node.cro=tail.cro;node.ver=tail.ver+1;node.dir=tail.dir;break;
            case U:node.cro=tail.cro+1;node.ver=tail.ver;node.dir=tail.dir;break;
            case R:node.cro=tail.cro;node.ver=tail.ver-1;node.dir=tail.dir;break;
            case D:node.cro=tail.cro-1;node.ver=tail.ver;node.dir=tail.dir;break;
        }
        snake.addLast(node);
    }

    public void removeTail(){//去蛇尾
        if (this.size()==1){return;}
        snake.removeLast();
    }

    public void move(){//移动方法,蛇头前+1方块，蛇尾-1方块
        if (snake.isAlive==false){return;}
        snake.addToHead();
        snake.removeTail();
//        snake.isAlive();
        snake.eat();
    }
    public void eat(){//判定是否吃到食物。若是，蛇加长尾巴,重新生成食物,加分数
        Node head = (Node) snake.getFirst();
        if(Food.cro==head.cro&& Food.ver==head.ver){
            snake.addToTail();
            Food.live=false;
            snake.score+= Food.foodScore;
        }
    }

    public void paintScore(){
        System.out.println("游戏结束 分数:"+score);
    }

    public void isAlive(){//判断蛇是否活
        Node head = (Node) snake.getFirst();//获得蛇头

        if(head.cro>Yard.CROSS_LINE||head.cro<3){//判定是否撞墙
            snake.isAlive=false;//把蛇弄死
            snake.isKeyLive=false;//把键盘锁死
            snake.paintScore();//打印分数
            return;
        }
        if (head.ver>Yard.VERTICAL_LINE||head.ver<1){//判定是否撞墙
            snake.isAlive=false;
            snake.isKeyLive=false;
            snake.paintScore();
            return;
        }

        while (snake.size()==1){return;}
        Iterator i = snake.iterator();//判定是否吃身体
        Node node;
        int count=0;
        while (i.hasNext()){
            node= (Node) i.next();
            if(count>0&&head.cro==node.cro&&head.ver==node.ver){//count>0条件,使得迭代器在获得第一个node，node即是头的时候,不能执行这句话,避免了头和head做比较,导致的直接判定蛇死亡
                snake.isAlive=false;
                snake.isKeyLive=false;
                snake.paintScore();
                return;
            }
            count++;
        }
    }


    public void changeDir(KeyEvent e){//改变蛇头方向
        if (snake.isAlive==false){return;}//蛇死后,不能改变方向
        Node head = (Node) snake.getFirst();
        switch (e.getKeyCode()){
            case KeyEvent.VK_LEFT:if (head.dir== Dir.R){return;}
                head.dir= Dir.L;
                break;
            case KeyEvent.VK_UP:if (head.dir== Dir.D){return;}
                head.dir= Dir.U;
                break;
            case KeyEvent.VK_RIGHT:if (head.dir== Dir.L){return;}
                head.dir= Dir.R;
                break;
            case KeyEvent.VK_DOWN:if(head.dir== Dir.U){return;}
                head.dir= Dir.D;
                break;
        }
        snake.removeFirst();
        snake.addFirst(head);
        Node n = (Node) snake.getFirst();
        System.out.println("行:"+n.cro+"  列:"+n.ver+"   方向:"+n.dir);
    }

    public Node getNextNode(Node node){//获取node的下一节，用于比较node是否是拐角
            Node temp;
            Node nextnode;
            Iterator iterator = snake.iterator();
            while (iterator.hasNext()){
                temp= (Node) iterator.next();
                if (temp.cro==node.cro&&temp.ver==node.ver&&temp.dir==temp.dir){
                    nextnode= (Node) iterator.next();
                    return nextnode;
                }
            }
            return null;
        }



    public void draw(Graphics g){//画蛇
        if(snake.size()<1){return;}
        int count = snake.size();
        Node node;
        Node befornode;
        Node nextnode;
        Iterator<Node> iterator = snake.iterator();
        node=iterator.next();//获得第一个元素即蛇头
        node.drawSnakeHead(g,node.dir);//画蛇头
        while (iterator.hasNext()){//接下来的都是蛇身了
            node=iterator.next();
            befornode=node;//存起来,是下一节的前一节
            if (node==snake.getLast()){//如果node是snake集合的最后一个,那他就是蛇尾
                node.drawSnakeTail(g,node.dir);
                return;
            }

            if (node!=snake.getFirst()){
                node.drawSnakeBody(g,node.dir);//画蛇身
            }

            if (snake.size()>2){//2节以上会出现拐角
                nextnode=snake.getNextNode(node);//获取下一节
                if (node.dir!=befornode.dir||node.dir!=nextnode.dir){//如果这节蛇身方向和之前的一节或者之后的一节不一样，那么他是个拐角
                    g.clearRect((node.ver-1)*node.blocksize,(node.cro-1)*node.blocksize,node.blocksize,node.blocksize);//把着个拐角原来的身体扣掉
                    node.drawCornerBody(g,befornode.dir,node.dir,nextnode.dir);//画拐角
                }
            }
        }

    }
}
